public with sharing class GetTemplateAttachmentsVF
{
    private final Sales_Contract__c[] sc = new Sales_Contract__c[1];
    private Attachment[] att = null;
    public List<Attachment> attachments {get; set;}
    private String attachmentIdVal = '';
    private String attachmentName = '';
    private String planStatus = '';
    private String viewedAttachmentId = '';
    public String viewedAttachmentName {get; set;}
    public String salesContractIdVal {get; set;}
    public String checkViewedAttachmentId {get; set;}
    public Boolean currentUserIdFlag {get; set;}
    public Boolean checkAcceptFlag {get; set;}
    static Boolean testVarFlag = false;
    static Sales_Contract__c[] testSalesContract;
    static Sales_Contract__c[] sContract;
    public Boolean isNonMerge {get; set;}
    
    static String testVar2 = '';
    
    private Map<String, Schema.SObjectField> scSObjectFieldMap = new Map<String, Schema.SObjectField>(); 
    private Map<String, Schema.SObjectField> urlSObjectFieldMap = new Map<String, Schema.SObjectField>(); 
    private Map<String, Schema.SObjectField> attachmentSObjectFieldMap = new Map<String, Schema.SObjectField>();  

    private DataAccessControlUtil dacu = null;
    private ID salesContractId;
    private String constructSoql;

    public String doNotAcceptUrl {get{doNotAcceptUrl = '/apex/Callidus_Plan__DoNotAccept';return doNotAcceptUrl;} set;}
   
    public Boolean isPlanDocAdmin {get; set;}

    public ID processInstanceWorkItemId {get; set;}
    private ProcessInstance[] prInst;
    private ProcessInstanceWorkitem[] prInstWItem; 
    public Boolean showApproveRejectButton {get; set;}
    
    public GetTemplateAttachmentsVF(ApexPages.StandardController myController) 
    {
        this.sc[0] = (Sales_Contract__c)myController.getRecord();
        salesContractId = sc[0].Id;
        
        dacu = new DataAccessControlUtil();
        SObject scObj = new Sales_Contract__c();

        scSObjectFieldMap = dacu.getFieldMap(scObj);
        
        String[] expectedFields = new String[]{'Status__c','ViewedAttachmentID__c','Viewed_Attachment_Name__c','Plan_Attachments__c','UserID__c'}; 
        Set<String> allowedFields = dacu.getAccessibleFields(scObj, scSObjectFieldMap, expectedFields);
        
        if(!allowedFields.isEmpty())
        {
            constructSoql = 'Select ';
            for(String roField: allowedFields)
            {
                constructSoql += roField+', ';
            }
            constructSoql = constructSoql.substring(0, constructSoql.length() - 2);
            constructSoql += ' from Sales_Contract__c s where s.Id = :salesContractId ';
            
            sContract = Database.query(constructSoql);//[select Status__c, ViewedAttachmentID__c,Viewed_Attachment_Name__c, Plan_Attachments__c,UserID__c from Sales_Contract__c s where s.Id = :sc[0].Id];
            salesContractIdVal = sc[0].Id;        
            planStatus = sContract[0].Status__c;
            viewedAttachmentId = sContract[0].ViewedAttachmentID__c;
            viewedAttachmentName = sContract[0].Viewed_Attachment_Name__c;
            currentUserIdFlag = false;
            isPlanDocAdmin = showApproveRejectButton = isNonMerge = false;

            Schema.Describesobjectresult scSobj = Sales_Contract__c.getSObjectType().getDescribe();
            if(scSObj.isAccessible() && scSObj.isCreateable() && scSObj.isUpdateable() && scSObj.isDeletable())
                isPlanDocAdmin = true;
                
            SObject urlObj = new URL__c();
            urlSObjectFieldMap = dacu.getFieldMap(urlObj);
            
            expectedFields = new String[]{'Plan_Doc_Type__c'}; 
            allowedFields = dacu.getAccessibleFields(urlObj, urlSObjectFieldMap, expectedFields);
            
            if(!allowedFields.isEmpty())
            {
                constructSoql = 'Select ';
                for(String roField: allowedFields)
                {
                    constructSoql += roField+', ';
                }
                constructSoql = constructSoql.substring(0, constructSoql.length() - 2);
                constructSoql += ' from URL__c limit 1 ';
                URL__c[] urlList = Database.query(constructSoql);//[select Plan_Doc_Type__c from URL__c limit 1];
                
                if(urlList.size() > 0 && urlList[0].Plan_Doc_Type__c == 'no' && sContract.size() > 0 && sContract[0].Plan_Attachments__c != null)
                {
                    isNonMerge = !isNonMerge;
                }
                
            }
            if(UserInfo.getUserId() == sContract[0].UserID__c)
                currentUserIdFlag = true;
                
            getTemplateAttachments();
            
	        prInst = [Select Id from ProcessInstance where TargetObjectId = :salesContractIdVal and Status = 'Pending'];
	        
	        if(prInst.size() > 0)
        	{
	        	prInstWItem = [select Id, OriginalActorId from ProcessInstanceWorkitem where ProcessInstanceId = :prInst[0].Id];
				if(prInstWItem.size() > 0 && prInstWItem[0].OriginalActorId == UserInfo.getUserId())
				{
					processInstanceWorkItemId = prInstWItem[0].id;
					showApproveRejectButton = !showApproveRejectButton;
				}            		
        	}
            
        } 
               
    }

    public String getPlanStatus()
    {
        return planStatus;
    }

    public void setPlanStatus(String s)
    {
        planStatus = s;
    }
    
    public PageReference numberOfAttachments()
    {
        SObject scObj = new Sales_Contract__c();
        String message = dacu.isUpdateableObjectByUser(scObj);
        
        if(message.equalsIgnoreCase('success'))
        {       
            if(scSObjectFieldMap.isEmpty())
                scSObjectFieldMap = dacu.getFieldMap(scObj);
            
            String[] expectedFields = new String[]{'TemplateName__c','UserID__c','AttachmentIdVals__c','Number_of_Attachments__c','Status__c'}; 
            Set<String> allowedFields = dacu.getAccessibleFields(scObj, scSObjectFieldMap, expectedFields);
            
            if(!allowedFields.isEmpty())
            {
                constructSoql = 'Select ';
                for(String roField: allowedFields)
                {
                    constructSoql += roField+', ';
                }
                constructSoql = constructSoql.substring(0, constructSoql.length() - 2);
                constructSoql += ' from Sales_Contract__c s where s.Id = :salesContractId ';
    
                sContract = Database.query(constructSoql);//[select TemplateName__c, UserID__c, AttachmentIdVals__c, Number_of_Attachments__c, Status__c from Sales_Contract__c where Id = :sc[0].Id];
                
                if(sContract.size() > 0 && UserInfo.getUserId() == sContract[0].UserID__c)
                {
                    scObj = sContract[0];

                    //Note: Whenever a new Custom field has to be updated, add it to the below Set.
                    //Reason: The size of the below set will be compared with the size of the filtered set 
                    Set<String> expectedUpdateableFields = new Set<String>{'Number_of_Attachments__c'};
                    
                    //Get the Fields that can be updated
                    Set<String> filteredFields = dacu.getFilteredUpdateableFields(scSObjectFieldMap, expectedUpdateableFields);
                    for(String s: filteredFields)
                    {
                        if(attachments != null)
                            scObj.put(s, Decimal.valueOf(attachments.size()));
                    }
                        
                                                    
                    if(!filteredFields.isEmpty())
                    {
                        try
                        {   
                            update scObj;
                        }
                        catch(Exception e)
                        {
                            ApexPages.addMessage(new Apexpages.Message(ApexPages.severity.info, e.getMessage()));
                        }
                    }

                    /*
                    sContract = [select TemplateName__c, UserID__c, AttachmentIdVals__c, Number_of_Attachments__c, Status__c from Sales_Contract__c where Id = :sc[0].Id];
                    if(UserInfo.getUserId() == sContract[0].UserID__c)
                    {
                        sContract[0].Number_of_Attachments__c = attachments.size();
                        update sContract;
                    }
                    */
                }
            }
        }
        return null;
    }

    public PageReference checkAndSaveViewedAttachmentId()
    {
        SObject scObj = new Sales_Contract__c();
        String message = dacu.isUpdateableObjectByUser(scObj);
        
        if(message.equalsIgnoreCase('success'))
        {       
            if(scSObjectFieldMap.isEmpty())
                scSObjectFieldMap = dacu.getFieldMap(scObj);
            
            String[] expectedFields = new String[]{'UserID__c','AttachmentIdVals__c','Number_of_Attachments__c'}; 
            Set<String> allowedFields = dacu.getAccessibleFields(scObj, scSObjectFieldMap, expectedFields);
    
            Sales_Contract__c[] checkContract = null;//[select AttachmentIdVals__c, UserID__c, Number_of_Attachments__c from Sales_Contract__c where id = :sc[0].Id];
            
            if(!allowedFields.isEmpty())
            {
                constructSoql = 'Select ';
                for(String roField: allowedFields)
                {
                    constructSoql += roField+', ';
                }
                constructSoql = constructSoql.substring(0, constructSoql.length() - 2);
                constructSoql += ' from Sales_Contract__c s where s.Id = :salesContractId ';
                
                checkContract = Database.query(constructSoql);

                if(checkContract.size() > 0 && Userinfo.getUserId() == checkContract[0].UserID__c)
                {
                    scObj = checkContract[0];
                    
                    //Note: Whenever a new Custom field has to be updated, add it to the below Set.
                    Set<String> expectedUpdateableFields = new Set<String>{'AttachmentIdVals__c'};
                    
                    //Get the filtered Fields that can be updated
                    Set<String> filteredFields = dacu.getFilteredUpdateableFields(scSObjectFieldMap, expectedUpdateableFields);
                    
                    if(checkContract[0].UserID__c == UserInfo.getUserId() && checkContract[0].AttachmentIdVals__c == null)
                    {

                        for(String s: filteredFields)
                            scObj.put(s, checkViewedAttachmentId);
                            
                                                        
                        if(!filteredFields.isEmpty())   
                        {
                            try
                            {   
                                update scObj;
                            }
                            catch(Exception e)
                            {
                                ApexPages.addMessage(new Apexpages.Message(ApexPages.severity.info, e.getMessage()));
                            }
                        }
                        
/*                      checkContract[0].AttachmentIdVals__c = checkViewedAttachmentId; 
                        update checkContract;*/
                        
                        if(checkContract[0].Number_of_Attachments__c == 1)
                            checkAcceptFlag = true;  
                    }
                    else if(checkContract[0].UserID__c == UserInfo.getUserId())
                    {
                        String[] splitViewedIds = checkContract[0].AttachmentIdVals__c.split(',');
                        Boolean idExists = false;
                        for(Integer i=0; i<splitViewedIds.size(); i++)
                        {
                            if(splitViewedIds[i] == checkViewedAttachmentId)
                            {
                                idExists = true;
                                break;
                            }
                        }
                        if(!idExists)
                        {
                            for(String s: filteredFields)
                                scObj.put(s, checkContract[0].AttachmentIdVals__c+','+checkViewedAttachmentId);
                                
                                                            
                            if(!filteredFields.isEmpty())   
                            {
                                try
                                {   
                                    update scObj;
                                }
                                catch(Exception e)
                                {
                                    ApexPages.addMessage(new Apexpages.Message(ApexPages.severity.info, e.getMessage()));
                                }
                            }
/*                          checkContract[0].AttachmentIdVals__c += ','+checkViewedAttachmentId;
                            update checkContract;*/
                        }
                        
                        splitViewedIds = checkContract[0].AttachmentIdVals__c.split(',');
                        if(splitViewedIds.size() == attachments.size())
                            checkAcceptFlag = true;
                        else
                            checkAcceptFlag = false;
                        
                    }
                }

    
            }
        }       
        
/*        Sales_Contract__c[] checkContract = [select AttachmentIdVals__c, UserID__c, Number_of_Attachments__c from Sales_Contract__c where id = :sc[0].Id];
        if(checkContract.size() > 0 && Userinfo.getUserId() == checkContract[0].UserID__c)
        {
            if(checkContract[0].UserID__c == UserInfo.getUserId() && checkContract[0].AttachmentIdVals__c == null)
            {
                checkContract[0].AttachmentIdVals__c = checkViewedAttachmentId; 
                update checkContract;
                
                if(checkContract[0].Number_of_Attachments__c == 1)
                    checkAcceptFlag = true;  
            }
            else if(checkContract[0].UserID__c == UserInfo.getUserId())
            {
                String[] splitViewedIds = checkContract[0].AttachmentIdVals__c.split(',');
                Boolean idExists = false;
                for(Integer i=0; i<splitViewedIds.size(); i++)
                {
                    if(splitViewedIds[i] == checkViewedAttachmentId)
                    {
                        idExists = true;
                        break;
                    }
                }
                if(!idExists)
                {
                    checkContract[0].AttachmentIdVals__c += ','+checkViewedAttachmentId;
                    update checkContract;
                }
                
                splitViewedIds = checkContract[0].AttachmentIdVals__c.split(',');
                if(splitViewedIds.size() == attachments.size())
                    checkAcceptFlag = true;
                else
                    checkAcceptFlag = false;
                
            }
        }*/
        return null;
    }
    
    public void setViewedAttachmentId(String aId)
    {
        viewedAttachmentId = aId;
    }
    
    public String getViewedAttachmentId()
    {
        return viewedAttachmentId;
    }
    
    public PageReference saveViewedId()
    {
        Attachment[] a = [select Name from Attachment where Id = :viewedAttachmentId];
        if(a.size() > 0)
        {
            viewedAttachmentName = a[0].Name;
        }
        
        
        SObject scObj = new Sales_Contract__c();
        String message = dacu.isUpdateableObjectByUser(scObj);
        
        if(message.equalsIgnoreCase('success'))
        {       
            if(scSObjectFieldMap.isEmpty())
                scSObjectFieldMap = dacu.getFieldMap(scObj);
            
            String[] expectedFields = new String[]{'Status__c','DateViewed__c','Viewed_Attachment_Name__c','ViewedAttachmentID__c','UserID__c'}; 
            Set<String> allowedFields = dacu.getAccessibleFields(scObj, scSObjectFieldMap, expectedFields);
    
            if(!allowedFields.isEmpty())
            {
                constructSoql = 'Select ';
                for(String roField: allowedFields)
                {
                    constructSoql += roField+', ';
                }
                constructSoql = constructSoql.substring(0, constructSoql.length() - 2);
                constructSoql += ' from Sales_Contract__c s where s.Id = :salesContractId ';

                sContract = Database.query(constructSoql);//[select Status__c, Viewed_Attachment_Name__c, ViewedAttachmentID__c, UserID__c from Sales_Contract__c where id = :sc[0].Id];
                
                scObj = sContract[0];

                //Note: Whenever a new Custom field has to be updated, add it to the below Set.
                Set<String> expectedUpdateableFields = new Set<String>{'Status__c','DateViewed__c','Viewed_Attachment_Name__c','ViewedAttachmentID__c'};
                
                //Store the expected updated fields and their values
                Map<String, Object> fieldsValMap = new Map<String, Object>();
                fieldsValMap.put('ViewedAttachmentID__c', viewedAttachmentId);
                fieldsValMap.put('Viewed_Attachment_Name__c', viewedAttachmentName);
                
                //sContract[0].ViewedAttachmentID__c = viewedAttachmentId;
                //sContract[0].Viewed_Attachment_Name__c = viewedAttachmentName;
                if(sContract[0].Status__c == 'Published' &&  sContract[0].UserID__c == UserInfo.getUserId())//if(isNonMerge && sContract[0].Status__c == 'Published' &&  sContract[0].UserID__c == UserInfo.getUserId())
                {
                    fieldsValMap.put('Status__c', 'Viewed');
                    fieldsValMap.put('DateViewed__c', Datetime.now());
                    //sContract[0].Status__c = 'Viewed';
                    //sContract[0].DateViewed__c = Datetime.now();
                }
                //Get the filtered Fields that can be updated
                Set<String> filteredFields = dacu.getFilteredUpdateableFields(scSObjectFieldMap, expectedUpdateableFields);
                
                //Update only fields with update permsission
                for(String s: filteredFields)
                {
                    if(!s.equalsIgnoreCase('DateViewed__c'))
                        scObj.put(s, (String)fieldsValMap.get(s));
                    else
                        scObj.put(s, (DateTime)fieldsValMap.get(s));
                }
                
                if(testVar2 != '' && testVar2.length() > 0)
                {
                    sContract[0].Level1__c = UserInfo.getUserId();
                    sContract[0].Level2__c = UserInfo.getUserId();
                    sContract[0].Level3__c = UserInfo.getUserId();
                    sContract[0].Level4__c = UserInfo.getUserId();
                    sContract[0].Level5__c = UserInfo.getUserId();
                    sContract[0].Level6__c = UserInfo.getUserId();
                    sContract[0].Level7__c = UserInfo.getUserId();
                    sContract[0].Level8__c = UserInfo.getUserId();
                    sContract[0].Level9__c = UserInfo.getUserId();
                    sContract[0].Level10__c = UserInfo.getUserId();
                    sContract[0].Level11__c = UserInfo.getUserId();
                    sContract[0].Level12__c = UserInfo.getUserId();
                    sContract[0].Level13__c = UserInfo.getUserId();
                    sContract[0].Level14__c = UserInfo.getUserId();
                    sContract[0].Level15__c = UserInfo.getUserId();
                    sContract[0].Final_Approver__c = UserInfo.getUserId();
                    sContract[0].Final_Approver_Date__c = Date.valueof('2008-06-26');
                }
        
                if(testVar2 == 'Published')
                {
                    scObj.put('Status__c', 'Published');
                }
                
                if(!filteredFields.isEmpty())   
                {
                    try
                    {   
                        update scObj;
                    }
                    catch(Exception e)
                    {
                        ApexPages.addMessage(new Apexpages.Message(ApexPages.severity.info, e.getMessage()));
                    }
                }
//              update sContract;
                
            }
        }
        return null;
    }

    public PageReference updateStatusToDistributedOrPublished()
    {
        SObject scObj = new Sales_Contract__c();
        String message = dacu.isUpdateableObjectByUser(scObj);
        
        if(message.equalsIgnoreCase('success'))
        {       
            if(scSObjectFieldMap.isEmpty())
                scSObjectFieldMap = dacu.getFieldMap(scObj);
            
            String[] expectedFields = new String[]{'Id','Status__c', 'Comments__c', 'Date_Rejected__c', 'Employee_Reject_Reason__c', 'Manager_Reject_Reason__c', 'Manager_Reject_Comment__c', 'Reject_Reason__c', 'Level1__c'}; 
            Set<String> allowedFields = dacu.getAccessibleFields(scObj, scSObjectFieldMap, expectedFields);
    
            if(!allowedFields.isEmpty())
            {
                constructSoql = 'Select ';
                for(String roField: allowedFields)
                {
                    constructSoql += roField+', ';
                }
                constructSoql = constructSoql.substring(0, constructSoql.length() - 2);
                constructSoql += ' from Sales_Contract__c s where s.Id = :salesContractId ';

                sContract = Database.query(constructSoql);//[select Status__c, Viewed_Attachment_Name__c, ViewedAttachmentID__c, UserID__c from Sales_Contract__c where id = :sc[0].Id];
                
                scObj = sContract[0];

                //Note: Whenever a new Custom field has to be updated, add it to the below Set.
                Set<String> expectedUpdateableFields = new Set<String>{'Status__c', 'Date_Rejected__c', 'Reject_Reason__c', 'Comments__c', 'Employee_Reject_Reason__c', 'Manager_Reject_Reason__c', 'Manager_Reject_Comment__c'};
                
                //Store the expected updated fields and their values
                Map<String, Object> fieldsValMap = new Map<String, Object>();
                if(scObj.get('Level1__c') != null)
                    fieldsValMap.put('Status__c', 'Distributed');
                else
                    fieldsValMap.put('Status__c', 'Published');
                    
                fieldsValMap.put('Employee_Reject_Reason__c', '');
                fieldsValMap.put('Reject_Reason__c', '');
                fieldsValMap.put('Manager_Reject_Reason__c', '');
                fieldsValMap.put('Manager_Reject_Comment__c', '');
                fieldsValMap.put('Comments__c', '');
                fieldsValMap.put('Date_Rejected__c', null);
                
                //Get the filtered Fields that can be updated
                Set<String> filteredFields = dacu.getFilteredUpdateableFields(scSObjectFieldMap, expectedUpdateableFields);
                
                //Update only fields with update permsission
                for(String s: filteredFields)
                {
                    if(!s.equalsIgnoreCase('Date_Rejected__c'))
                        scObj.put(s, (String)fieldsValMap.get(s));
                    else
                        scObj.put(s, (DateTime)fieldsValMap.get(s));
                }

                if(!filteredFields.isEmpty())   
                {
                    update scObj;

                    if(scObj.get('Status__c') == 'Distributed')
                    {
                        Approval.ProcessSubmitRequest request = new Approval.ProcessSubmitRequest();
                        request.setObjectId((ID)scObj.get('Id'));
                        Approval.ProcessResult result = Approval.process(request);
                    }   
                }
            }
        }
        return null;
    }
    
    public PageReference savePlanViewedId()
    {
        Attachment[] a = [select Name from Attachment where Id = :viewedAttachmentId];
        if(a.size() > 0)
        {
            viewedAttachmentName = a[0].Name;
        }
        
        
        SObject scObj = new Sales_Contract__c();
        String message = dacu.isUpdateableObjectByUser(scObj);
        
        if(message.equalsIgnoreCase('success'))
        {       
            if(scSObjectFieldMap.isEmpty())
                scSObjectFieldMap = dacu.getFieldMap(scObj);
            
            String[] expectedFields = new String[]{'Status__c','DateViewed__c','Viewed_Attachment_Name__c','ViewedAttachmentID__c','UserID__c'}; 
            Set<String> allowedFields = dacu.getAccessibleFields(scObj, scSObjectFieldMap, expectedFields);
    
            if(!allowedFields.isEmpty())
            {
                constructSoql = 'Select ';
                for(String roField: allowedFields)
                {
                    constructSoql += roField+', ';
                }
                constructSoql = constructSoql.substring(0, constructSoql.length() - 2);
                constructSoql += ' from Sales_Contract__c s where s.Id = :salesContractId ';

                sContract = Database.query(constructSoql);//[select Status__c, Viewed_Attachment_Name__c, ViewedAttachmentID__c, UserID__c from Sales_Contract__c where id = :sc[0].Id];
                
                scObj = sContract[0];

                //Note: Whenever a new Custom field has to be updated, add it to the below Set.
                Set<String> expectedUpdateableFields = new Set<String>{'Status__c','DateViewed__c','Viewed_Attachment_Name__c','ViewedAttachmentID__c'};
                
                //Store the expected updated fields and their values
                Map<String, Object> fieldsValMap = new Map<String, Object>();
                fieldsValMap.put('ViewedAttachmentID__c', viewedAttachmentId);
                fieldsValMap.put('Viewed_Attachment_Name__c', viewedAttachmentName);
                
                if(sContract[0].Status__c == 'Published' &&  sContract[0].UserID__c == UserInfo.getUserId())//if(isNonMerge && sContract[0].Status__c == 'Published' &&  sContract[0].UserID__c == UserInfo.getUserId())
                {
                    fieldsValMap.put('Status__c', 'Viewed');
                    fieldsValMap.put('DateViewed__c', Datetime.now());
                }
                //Get the filtered Fields that can be updated
                Set<String> filteredFields = dacu.getFilteredUpdateableFields(scSObjectFieldMap, expectedUpdateableFields);
                
                //Update only fields with update permsission
                for(String s: filteredFields)
                {
                    if(!s.equalsIgnoreCase('DateViewed__c'))
                        scObj.put(s, (String)fieldsValMap.get(s));
                    else
                        scObj.put(s, (DateTime)fieldsValMap.get(s));
                }
                
                if(testVar2 != '' && testVar2.length() > 0)
                {
                    sContract[0].Level1__c = UserInfo.getUserId();
                    sContract[0].Level2__c = UserInfo.getUserId();
                    sContract[0].Level3__c = UserInfo.getUserId();
                    sContract[0].Level4__c = UserInfo.getUserId();
                    sContract[0].Level5__c = UserInfo.getUserId();
                    sContract[0].Level6__c = UserInfo.getUserId();
                    sContract[0].Level7__c = UserInfo.getUserId();
                    sContract[0].Level8__c = UserInfo.getUserId();
                    sContract[0].Level9__c = UserInfo.getUserId();
                    sContract[0].Level10__c = UserInfo.getUserId();
                    sContract[0].Level11__c = UserInfo.getUserId();
                    sContract[0].Level12__c = UserInfo.getUserId();
                    sContract[0].Level13__c = UserInfo.getUserId();
                    sContract[0].Level14__c = UserInfo.getUserId();
                    sContract[0].Level15__c = UserInfo.getUserId();
                    sContract[0].Final_Approver__c = UserInfo.getUserId();
                    sContract[0].Final_Approver_Date__c = Date.valueof('2008-06-26');
                }
        
                if(testVar2 == 'Published')
                {
                    scObj.put('Status__c', 'Published');
                }
                
                if(!filteredFields.isEmpty())   
                {
                    try
                    {   
                        update scObj;
                    }
                    catch(Exception e)
                    {
                        ApexPages.addMessage(new Apexpages.Message(ApexPages.severity.info, e.getMessage()));
                    }
                }
                
            }
        }
        return null;
    }
    

    public String getAttachmentIdVal()
    {
        SObject scObj = new Sales_Contract__c();
        if(scSObjectFieldMap.isEmpty())
            scSObjectFieldMap = dacu.getFieldMap(scObj);
        
        String[] expectedFields = new String[]{'AttachmentID__c'}; 
        Set<String> allowedFields = dacu.getAccessibleFields(scObj, scSObjectFieldMap, expectedFields);

        if(!allowedFields.isEmpty())
        {
            constructSoql = 'Select ';
            for(String roField: allowedFields)
            {
                constructSoql += roField+', ';
            }
            constructSoql = constructSoql.substring(0, constructSoql.length() - 2);
            constructSoql += ' from Sales_Contract__c s where s.Id = :salesContractId ';
            
            Sales_Contract__c[] sCon = Database.query(constructSoql);//[select AttachmentID__c from Sales_Contract__c s where s.Id = : sc[0].Id];
            if(sCon.size() > 0)        
                attachmentIdVal = sCon[0].AttachmentID__c;
            return attachmentIdVal;
                
        }
        return null;
    }
    
    public void setAttachmentIdVal(String attachVal)
    {
        attachmentIdVal = attachVal;
    }

    public String getAttachmentName()
    {
        Attachment[] attach = [select Name from Attachment where Id = :attachmentIdVal];
        if(attach.size() > 0)
            attachmentName =  attach[0].Name;      
            
        return attachmentName;
    }
    
    public void setAttachmentName(String name)
    {
        attachmentName = name;
    }
    

    public PageReference updateStatusToPD()
    {
        SObject scObj = new Sales_Contract__c();
        String message = dacu.isUpdateableObjectByUser(scObj);
        
        if(message.equalsIgnoreCase('success'))
        {       
            if(scSObjectFieldMap.isEmpty())
                scSObjectFieldMap = dacu.getFieldMap(scObj);
            
            String[] expectedFields = new String[]{'Id','Status__c', 'Comments__c', 'Date_Rejected__c', 'Employee_Reject_Reason__c', 'Manager_Reject_Reason__c', 'Manager_Reject_Comment__c', 'Reject_Reason__c', 'Level1__c'}; 
            Set<String> allowedFields = dacu.getAccessibleFields(scObj, scSObjectFieldMap, expectedFields);
    
            if(!allowedFields.isEmpty())
            {
                constructSoql = 'Select ';
                for(String roField: allowedFields)
                {
                    constructSoql += roField+', ';
                }
                constructSoql = constructSoql.substring(0, constructSoql.length() - 2);
                constructSoql += ' from Sales_Contract__c s where s.Id = :salesContractId ';

                sContract = Database.query(constructSoql);//[select Status__c, Viewed_Attachment_Name__c, ViewedAttachmentID__c, UserID__c from Sales_Contract__c where id = :sc[0].Id];
                
                scObj = sContract[0];

                //Note: Whenever a new Custom field has to be updated, add it to the below Set.
                Set<String> expectedUpdateableFields = new Set<String>{'Status__c', 'Date_Rejected__c', 'Reject_Reason__c', 'Comments__c', 'Employee_Reject_Reason__c', 'Manager_Reject_Reason__c', 'Manager_Reject_Comment__c'};
                
                //Store the expected updated fields and their values
                Map<String, Object> fieldsValMap = new Map<String, Object>();
                if(scObj.get('Level1__c') != null)
                    fieldsValMap.put('Status__c', 'Distributed');
                else
                    fieldsValMap.put('Status__c', 'Published');
                    
                fieldsValMap.put('Employee_Reject_Reason__c', '');
                fieldsValMap.put('Reject_Reason__c', '');
                fieldsValMap.put('Manager_Reject_Reason__c', '');
                fieldsValMap.put('Manager_Reject_Comment__c', '');
                fieldsValMap.put('Comments__c', '');
                fieldsValMap.put('Date_Rejected__c', null);
                
                //Get the filtered Fields that can be updated
                Set<String> filteredFields = dacu.getFilteredUpdateableFields(scSObjectFieldMap, expectedUpdateableFields);
                
                //Update only fields with update permsission
                for(String s: filteredFields)
                {
                    if(!s.equalsIgnoreCase('Date_Rejected__c'))
                        scObj.put(s, (String)fieldsValMap.get(s));
                    else
                        scObj.put(s, (DateTime)fieldsValMap.get(s));
                }

                if(!filteredFields.isEmpty())   
                {
                    update scObj;

                    if(scObj.get('Status__c') == 'Distributed')
                    {
                        Approval.ProcessSubmitRequest request = new Approval.ProcessSubmitRequest();
                        request.setObjectId((ID)scObj.get('Id'));
                        Approval.ProcessResult result = Approval.process(request);
                    }   
                }
            }
        }
        return null;
    }
    
    
    private Attachment[] getTemplateAttachments()
    {
        SObject scObj = new Sales_Contract__c();
        if(scSObjectFieldMap.isEmpty())
            scSObjectFieldMap = dacu.getFieldMap(scObj);
        
        String[] expectedFields = new String[]{'TemplateName__c','AttachmentID__c','UserID__c','AttachmentIdVals__c','Number_of_Attachments__c','Plan_Attachments__c','Status__c'}; 
        Set<String> allowedFields = dacu.getAccessibleFields(scObj, scSObjectFieldMap, expectedFields);

        if(!allowedFields.isEmpty())
        {
            constructSoql = 'Select ';
            for(String roField: allowedFields)
            {
                constructSoql += roField+', ';
            }
            constructSoql = constructSoql.substring(0, constructSoql.length() - 2);
            constructSoql += ' from Sales_Contract__c s where s.Id = :salesContractId ';
            
            sContract = Database.query(constructSoql);//[select TemplateName__c, AttachmentID__c, UserID__c, AttachmentIdVals__c, Number_of_Attachments__c, Plan_Attachments__c, Status__c from Sales_Contract__c where Id = :sc[0].Id];
            Template__c[] t =new Template__c[]{};
            attachments = new List<Attachment>();
            
            if(isNonMerge)
            {
                String[] aVals = sContract[0].Plan_Attachments__c.split(',');
                Map<ID, ID> aValMap = new Map<ID, ID>();  
                if(aVals.size() > 0)
                {
                    for(Integer i=0; i<(aVals.size()); i++)
                    {
                        aValMap.put(aVals[i], aVals[i]);
                    }
                }
                att = [SELECT Id, Name FROM Attachment a where a.Id in :aValMap.keyset()];
                    
                if(att != null && att.size() > 0)
                {
                    for(Integer i=0;i<att.size();i++)
                    {
                        attachments.add(att[i]);
                    }
                }
                    
                if(attachments.size() == 0)
                    attachments = null;
        
                if(scontract[0].AttachmentIdVals__c != null)
                {
                    String[] splittedIdVals = scontract[0].AttachmentIdVals__c.split(',');
                    if(splittedIdVals.size() == attachments.size())
                        checkAcceptFlag = true;
                    else
                        checkAcceptFlag = false;
                }
                
                
            }
            else
            {
                if(sContract.size() > 0)
                {
                    t = [select Id from Template__c where Name = :sContract[0].TemplateName__c];
                }
                
                if(t.size() > 0)
                {
                    att = [SELECT Id, Name, ContentType, Body FROM Attachment a where a.ParentId = :t[0].Id];
                }
                if(att.size() > 0)
                {
                    for(Integer i=0;i<att.size();i++)
                    {
                        if(att[i].Id == sContract[0].AttachmentID__c)
                        {
                            attachments.add(att[i]);
                        }
                        else if(att[i].Name.indexOf('.doc') != -1 || att[i].Name.indexOf('.rtf') != -1) 
                            attachments.add(att[i]);
                    }
            
                    String body = '';
                    for(Integer i=0;i<att.size();i++)
                    {
                        if(att[i].Id != sContract[0].AttachmentID__c)
                        {
                            if(att[i].Body != null)
                            {
                                body = att[i].Body.toString();
                                Integer indexOfBody = body.indexOf('<body', 0);
                                if(indexOfBody == -1)
                                    indexOfBody = body.indexOf('<Body', 0);
                
                                if(indexOfBody == -1)
                                    indexOfBody = body.indexOf('<BODY', 0);
                                
                                String extractedBody = '';
                                if(indexOfBody != -1)
                                {
                                    extractedBody = body.substring(indexOfBody);
                                
                                    Integer indexOfLFB = extractedBody.indexOf('{', 0);
                                    Integer indexOfRFB = extractedBody.indexOf('}', 0);
                                    
                                    if(indexOfLFB == -1 && indexOfRFB == -1)
                                    {
                                        attachments.add(att[i]);
                                    }
                                }
                            }   
                        }//end of if
                    }//end of for
                    if(attachments.size() == 0)
                        attachments = null;
            
                    if(scontract[0].AttachmentIdVals__c != null)
                    {
                        String[] splittedIdVals = scontract[0].AttachmentIdVals__c.split(',');
                        if(splittedIdVals.size() == attachments.size())
                            checkAcceptFlag = true;
                        else
                            checkAcceptFlag = false;
                    }
                }               
            }
        }
                
        
        
/*      sContract = [select TemplateName__c, AttachmentID__c, UserID__c, AttachmentIdVals__c, Number_of_Attachments__c, Plan_Attachments__c, Status__c from Sales_Contract__c where Id = :sc[0].Id];
        Template__c[] t;
        attachments = new List<Attachment>();
        
        if(isNonMerge)
        {
            String[] aVals = sContract[0].Plan_Attachments__c.split(',');
            Map<ID, ID> aValMap = new Map<ID, ID>();  
            if(aVals.size() > 0)
            {
                for(Integer i=0; i<(aVals.size()); i++)
                {
                    aValMap.put(aVals[i], aVals[i]);
                }
            }
            att = [SELECT Id, Name FROM Attachment a where a.Id in :aValMap.keyset()];
                
            if(att != null && att.size() > 0)
            {
                for(Integer i=0;i<att.size();i++)
                {
                    attachments.add(att[i]);
                }
            }
                
            if(attachments.size() == 0)
                attachments = null;
    
            if(scontract[0].AttachmentIdVals__c != null)
            {
                String[] splittedIdVals = scontract[0].AttachmentIdVals__c.split(',');
                if(splittedIdVals.size() == attachments.size())
                    checkAcceptFlag = true;
                else
                    checkAcceptFlag = false;
            }
            
            
        }
        else
        {
            if(sContract.size() > 0)
            {
                t = [select Id, Name from Template__c where Name = :sContract[0].TemplateName__c];
            }
            
            if(t.size() > 0)
            {
                att = [SELECT Id, Name, ContentType, Body FROM Attachment a where a.ParentId = :t[0].Id];
            }
            
            for(Integer i=0;i<att.size();i++)
            {
                if(att[i].Id == sContract[0].AttachmentID__c)
                {
                    attachments.add(att[i]);
                }
                else if(att[i].Name.indexOf('.doc') != -1 || att[i].Name.indexOf('.rtf') != -1) 
                    attachments.add(att[i]);
            }
    
            String body = '';
            for(Integer i=0;i<att.size();i++)
            {
                if(att[i].Id != sContract[0].AttachmentID__c)
                {
                    if(att[i].Body != null)
                    {
                        body = att[i].Body.toString();
                        Integer indexOfBody = body.indexOf('<body', 0);
                        if(indexOfBody == -1)
                            indexOfBody = body.indexOf('<Body', 0);
        
                        if(indexOfBody == -1)
                            indexOfBody = body.indexOf('<BODY', 0);
                        
                        String extractedBody = '';
                        if(indexOfBody != -1)
                        {
                            extractedBody = body.substring(indexOfBody);
                        
                            Integer indexOfLFB = extractedBody.indexOf('{', 0);
                            Integer indexOfRFB = extractedBody.indexOf('}', 0);
                            
                            if(indexOfLFB == -1 && indexOfRFB == -1)
                            {
                                attachments.add(att[i]);
                            }
                        }
                    }   
                }//end of if
            }//end of for
            if(attachments.size() == 0)
                attachments = null;
    
            if(scontract[0].AttachmentIdVals__c != null)
            {
                String[] splittedIdVals = scontract[0].AttachmentIdVals__c.split(',');
                if(splittedIdVals.size() == attachments.size())
                    checkAcceptFlag = true;
                else
                    checkAcceptFlag = false;
            }
            
        }
        */
        return attachments;
    }
    
    public PageReference getPlanDetails()
    {
        SObject scObj = new Sales_Contract__c();
        if(scSObjectFieldMap.isEmpty())
            scSObjectFieldMap = dacu.getFieldMap(scObj);
        
        String[] expectedFields = new String[]{'Id', 'Name','FirstName__c','LastName__c','UserID__c','UserRoleId__c','UserRoleName__c','Name1__c','Name2__c','Name3__c','Name4__c','Name5__c','Name6__c','Name7__c','Name8__c','Name9__c','Name10__c','Name11__c','Name12__c','Name13__c','Name14__c','Name15__c','Name16__c','Name17__c','Name18__c','Name19__c','Name20__c','Name21__c','Name22__c','Name23__c','Name24__c','Name25__c','Name26__c','Name27__c','Name28__c','Name29__c','Name30__c','Value1__c','Value2__c','Value3__c','Value4__c','Value5__c','Value6__c','Value7__c','Value8__c','Value9__c','Value10__c','Value11__c','Value12__c','Value13__c','Value14__c','Value15__c','Value16__c','Value17__c','Value18__c','Value19__c','Value20__c','Value21__c','Value22__c','Value23__c','Value24__c','Value25__c','Value26__c','Value27__c','Value28__c','Value29__c','Value30__c','Name31__c','Name32__c','Name33__c','Name34__c','Name35__c','Name36__c','Name37__c','Name38__c','Name39__c','Name40__c','Name41__c','Name42__c','Name43__c','Name44__c','Name45__c','Name46__c','Name47__c','Name48__c','Name49__c','Name50__c','Name51__c','Name52__c','Name53__c','Name54__c','Value31__c','Value32__c','Value33__c','Value34__c','Value35__c','Value36__c','Value37__c','Value38__c','Value39__c','Value40__c','Value41__c','Value42__c','Value43__c','Value44__c','Value45__c','Value46__c','Value47__c','Value48__c','Value49__c','Value50__c','Value51__c','Value52__c','Value53__c','Value54__c','TemplateName__c','AttachmentID__c','UserID__c','AttachmentIdVals__c','Number_of_Attachments__c','Plan_Attachments__c','Status__c'}; 
        Set<String> allowedFields = dacu.getAccessibleFields(scObj, scSObjectFieldMap, expectedFields);

        if(!allowedFields.isEmpty())
        {
            constructSoql = 'Select ';
            for(String roField: allowedFields)
            {
                constructSoql += roField+', ';
            }
            constructSoql = constructSoql.substring(0, constructSoql.length() - 2);
            constructSoql += ' from Sales_Contract__c s where s.Id = :salesContractId ';
            sContract = Database.query(constructSoql);//[select TemplateName__c, AttachmentID__c, UserID__c, AttachmentIdVals__c, Number_of_Attachments__c, Plan_Attachments__c, Status__c from Sales_Contract__c where Id = :sc[0].Id];
        }       
        return null;
    }
    
    static testMethod void testGetTemplateAttachmentsVF() 
    {
        
        PageReference pg = Page.TemplateAttachments;
        
        Test.setCurrentPage(pg);
        
        Template__c t = new Template__c(name = 'Test12321');
        insert t;
        Template__c[] tempT = [select name from Template__c where id = :t.id];
        system.assertEquals(t.name, tempT[0].name);

        Attachment a = new Attachment(name = 'Test Attach.doc', Body = Blob.valueOf('<html><body>This is {Attachment}</body></html>'), parentId = t.Id);
        insert a;
        Attachment[] attT = [select name, Body, Parentid from Attachment where id = :a.id];
        system.assertEquals(a.name, attT[0].name);
        system.assertEquals(a.Body.toString(), attT[0].Body.toString());
        system.assertEquals(a.ParentId, attT[0].ParentId);
        
        Attachment a1 = new Attachment(name = 'Test', Body = Blob.valueOf('<html><body>This is {Attachment}</body></html>'), parentId = t.Id);
        insert a1;
        attT = [select name, Body, Parentid from Attachment where id = :a.id];
        system.assertEquals(a.name, attT[0].name);
        system.assertEquals(a.Body.toString(), attT[0].Body.toString());
        system.assertEquals(a.ParentId, attT[0].ParentId);
        
        Sales_Contract__c sc = new Sales_Contract__c(TemplateName__c = t.name, UserID__c = UserInfo.getUserId(), AttachmentID__c = a.id, AttachmentIdVals__c = a.Id, Number_of_Attachments__c = 1, Status__c = 'Viewed');
        insert sc;
        Sales_Contract__c[] scT = [select id from Sales_Contract__c where id = :sc.Id];
        system.assertEquals(sc.id, scT[0].id);
                
        ApexPages.StandardController mc = new Apexpages.Standardcontroller(sc);

        GetTemplateAttachmentsVF gtvf = new GetTemplateAttachmentsVF(mc);
        if(sContract.size() > 0)
        {
            gtvf.getTemplateAttachments();
            gtvf.setPlanStatus('Viewed');  
            system.assertEquals(gtvf.planStatus, gtvf.getPlanStatus());
            gtvf.getTemplateAttachments();
            gtvf.setAttachmentIdVal(a.id);
            system.assertEquals(a.id, gtvf.getAttachmentIdVal());
            gtvf.setAttachmentName(a.Name);
            system.assertEquals(a.Name, gtvf.getAttachmentName());
            gtvf.setViewedAttachmentId(a.Id);
            system.assertEquals(a.Id, gtvf.getViewedAttachmentId());
            
            testVar2 = 'Published';
			gtvf.updateStatusToDistributedOrPublished();            
            system.assertEquals(null, gtvf.saveViewedId());
            System.assertEquals(null, gtvf.numberOfAttachments());
            
            system.assertEquals(null, gtvf.checkAndSaveViewedAttachmentId());
            system.assertEquals(null, gtvf.savePlanViewedId());
            system.assertEquals(null, gtvf.updateStatusToPD());
            system.assertEquals(null, gtvf.getPlanDetails());
        }       
    }
    
    static testMethod void dacuTestCase() 
    {
        DataAccessControlUtil dacu = new DataAccessControlUtil();
        SObject sObj = new CallidusDataSOurce__c();
        Map<String, Schema.Sobjectfield> fieldsMap = dacu.getFieldMap(sObj);
        String[] expectedFieldMap = new String[]{'Id','Name'};
        Set<String> allowedFields = dacu.getAccessibleFields(sObj, fieldsMap, expectedFieldMap);
        Set<String> filteredList = dacu.getFilteredCreateableFields(fieldsMap, allowedFields);
        filteredList = dacu.getFilteredUpdateableFields(fieldsMap, allowedFields);
        system.assertEquals('success', dacu.isCreateableObjectByUser(sObj));
        system.assertEquals('success', dacu.isUpdateableObjectByUser(sObj));
        system.assertEquals('success', dacu.isDeleteableObjectByUser(sObj));
        dacu.pageMessage(sobj, 'create');
    }
}